<!-- 优惠券管理页面 -->
<template>
    <div>
        <!-- 搜索框 -->
        <div class="grid-content">
            <el-input placeholder="请输入优惠卷名称" v-model="data.title" class="m-2" clearable />
            <el-select v-model="data.type" clearable placeholder="请选择优惠卷类型" class="m-2">
                <el-option v-for="item in couponTypeMap" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
            <el-select v-model="data.status" clearable placeholder="请选择优惠卷状态" class="m-2">
                <el-option v-for="item in couponStatusMap" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
            <el-button type="primary" :icon="Search" @click="init">查找</el-button>
            <el-button type="primary" :icon="Plus" @click="handlePageAdd"
                v-permission="'promotion:coupon:create'">添加</el-button>
            <el-button type="primary" :icon="Download" @click="derive">当前页导出</el-button>
        </div>
        <!-- 优惠卷表格 -->
        <el-table :data="tableData" id="exportTab" border style="width: 100%" :cell-style="{ textAlign: 'center' }"
            :header-cell-style="{ 'text-align': 'center' }">
            <el-table-column prop="id" label="优惠券ID" sortable width="120" />
            <el-table-column prop="title" label="优惠券名称" width="120" />
            <el-table-column label="优惠券类型" width="120">
                <template #default="scope">
                    {{ scope.row.type == 1 ? '满减券' : '立减券' }}
                </template>
            </el-table-column>
            <el-table-column prop="description" label="介绍" width="120" />
            <el-table-column prop="total" label="优惠券数量" width="120" />
            <el-table-column prop="surplus" label="剩余数量" width="120" />
            <el-table-column prop="limit" label="每人限领" width="120" />
            <el-table-column label="满减金额" width="120">
                <template #default="scope">
                    {{ `减免${scope.row.discount}元` }}
                </template>
            </el-table-column>
            <el-table-column label="最低消费" width="120">
                <template #default="scope">
                    {{ `满${scope.row.min}元可用` }}
                </template>
            </el-table-column>
            <el-table-column label="状态" width="120">
                <template #default="scope">
                    <el-tag :type="scope.row.status == -1 ? 'danger' : scope.row.status == 1 ? '' : 'danger'">
                        {{ handleStatus(scope.row) }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="使用类名名称" width="120">
                <template #default="scope">
                    <el-tag>
                        {{ scope.row.categoryTitle == undefined ? '全部类名' : scope.row.categoryTitle }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="categoryId" label="使用类名ID" width="120" />
            <el-table-column label="领券相对天数" width="120">
                <template #default="scope">
                    {{ scope.row.days == undefined ? '无' : scope.row.days }}
                </template>
            </el-table-column>
            <el-table-column label="领券开始时间" width="120">
                <template #default="scope">
                    {{ filDateTime(scope.row.gmtStart) }}
                </template>
            </el-table-column>
            <el-table-column label="领券结束时间" width="120">
                <template #default="scope">
                    {{ filDateTime(scope.row.gmtEnd) }}
                </template>
            </el-table-column>
            <el-table-column label="操作" width="200">
                <template #default="scope">
                    <el-button :type="scope.row.status == -1 ? 'primary' : scope.row.status == 1 ? 'danger' : 'primary'"
                        @click="modifyState(scope.$index, scope.row)">
                        {{ handleStatusBtn(scope.row.status) }}
                    </el-button>
                    <el-button type="info" @click="survey(scope.row)">
                        查看
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
        <Pagination v-bind="pagination" @page-change="handlePageChange" /><!--分页器-->
        <!-- 添加查看弹框 -->
        <el-dialog v-model="dialogFormVisible" :title="dialogTitle" width="700">
            <el-form :model="form" label-position="left" label-width="100px" :rules="rules" ref="ruleFormRef"
                :disabled="dialogType">
                <el-form-item label="优惠券名称" prop="title">
                    <el-input v-model="form.title" />
                </el-form-item>
                <el-form-item label="优惠券类型" prop="type">
                    <el-select v-model="form.type" clearable>
                        <el-option v-for="item in couponTypeMap" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="介绍">
                    <el-input v-model="form.description" />
                </el-form-item>
                <el-form-item label="优惠券数量" prop="total">
                    <el-input v-model="form.total">
                        <template #append>张</template>
                    </el-input>
                </el-form-item>
                <el-form-item label="每人限领" prop="limit">
                    <el-input v-model="form.limit">
                        <template #append>张</template>
                    </el-input>
                </el-form-item>
                <el-form-item label="优惠金额" prop="discount">
                    <el-input v-model="form.discount">
                        <template #append>元</template>
                    </el-input>
                </el-form-item>
                <el-form-item label="最低消费" prop="min">
                    <el-input v-model="form.min">
                        <template #append>元</template>
                    </el-input>
                </el-form-item>
                <el-form-item label="优惠券状态" prop="status">
                    <el-select v-model="form.status" clearable>
                        <el-option v-for="item in couponStatusMap" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="有效期">
                    <el-button-group>
                        <el-button :type="isInput ? 'primary' : ''" @click="isInput = true">领券相对天数</el-button>
                        <el-button :type="isInput ? '' : 'primary'" @click="isInput = false">指定绝对时间</el-button>
                    </el-button-group>
                    <el-input class="m-3" v-model="form.days" v-if="isInput">
                        <template #append>天</template>
                    </el-input>
                    <div class="picker" v-else>
                        <el-date-picker v-model="form.gmtStart" type="datetime" placeholder="选择日期"
                            @change="getStartTime" />
                        <span>至</span>
                        <el-date-picker v-model="form.gmtEnd" type="datetime" placeholder="选择日期" @change="getEndTime" />
                    </div>
                </el-form-item>
                <el-form-item label="商品限制范围">
                    <el-button-group>
                        <el-button :type="isCascader ? 'primary' : ''" @click="isCascader = true">全场通用</el-button>
                        <el-button :type="isCascader ? '' : 'primary'" @click="isCascader = false">指定分类</el-button>
                    </el-button-group>
                </el-form-item>
                <el-form-item label="优惠类目" v-if="!isCascader">
                    <el-cascader v-model="form.categoryId" :options="categoryData" @change="handleChange" clearable
                        :props="{ checkStrictly: true, label: 'title', value: 'id', children: 'childrenList' }" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogFormVisible = false">取消</el-button>
                    <el-button type="primary" @click="determine(ruleFormRef)">
                        确定
                    </el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch, computed } from "vue";
import { Search, Plus, Download } from '@element-plus/icons-vue';//图标 
import { post } from "@/utils/http"; //封装的axios请求方式
import { ElMessage } from 'element-plus'//提示信息
import { filDateTime } from "@/utils/time";//时间戳处理
import { PaginationClass, CouponClass } from "#/index";//数据类型
import type { FormInstance } from 'element-plus'//form的数据类型
import FileSaver from 'file-saver'//引入file-saver插件，表格导出excel格式
import * as XLSX from 'xlsx'

const ruleFormRef = ref<FormInstance>()//操作form节点
const pagination = ref(new PaginationClass())//分页数据
const tableData = ref([])//表格数据
const categoryData = ref([])//类目数据
const dialogFormVisible = ref(false)//控制弹框隐藏显示
const couponTypeMap = [ //优惠券类型
    { value: 1, label: '满减券' },
    { value: 2, label: '立减券' },
    { value: '', label: '全部' }
]
const couponStatusMap = [ //优惠券状态
    { value: 0, label: '下架' },
    { value: 1, label: '正常' },
    { value: -1, label: '已过期' },
    { value: '', label: '全部' }
]

class FormClass extends CouponClass {
    /**
     * 有效期类型 0:相对天数 1:指定时间
     */
    timeType = 0 | 1;
    /**
     * 商品限制范围 0:全场通用 1:指定范围
     */
    goodsType = 0 | 1
}

let dialogTitle = computed(() => dialogType.value == false ? '创建' : '查看')//判断弹框标题
let dialogType = ref(false) //控制弹框的类型
let isInput = ref(true) //控制弹框中有效期显示隐藏
let isCascader = ref(true) //控制弹框中商品限制范围显示隐藏

let form = ref(new FormClass())//弹框绑定数据

let data = ref({//请求传递的数据
    _gp: 'admin.coupon',
    _mt: 'list',
    title: '',//优惠券标题
    type: undefined,//优惠券类型
    status: undefined,//优惠券状态
    pageNo: 1,//当前的页数
    limit: 10//每页显示条数
})

// 非空验证
const rules = ref({
    title: [{ required: true, message: '优惠卷名称不能为空', trigger: 'blur' }],
    type: [{ required: true, message: '优惠卷类型不能为空', trigger: 'change' }],
    total: [
        { required: true, message: '优惠卷数量不能为空', trigger: 'blur' },
        { required: true, pattern: /^[0-9]*$/, message: '请输入整数' }],
    discount: [
        { required: true, message: '优惠金额不能空', trigger: 'blur' },
        { required: true, pattern: /^[0-9]*$/, message: '请输入整数' }
    ],
    status: [
        { required: true, message: '状态不能为空', trigger: 'change' }
    ],
    limit: [
        { required: true, message: '每人限领不能为空', trigger: 'change' },
        { required: true, pattern: /^[0-9]*$/, message: '请输入整数' }
    ],
    min: [
        { required: true, message: '每人限领不能为空', trigger: 'change' },
        { required: true, pattern: /^[0-9]*$/, message: '请输入整数' }
    ]
})

onMounted(() => {
    init()
})

// 监听有效期显示隐藏、商品限制范围显示隐藏数据，如果发生变化则改变有效期类型、商品限制范围类型
watch([() => isInput.value, () => isCascader.value, () => form.value.timeType, () => form.value.goodsType],
    (newValue, oldValue) => {
        // 判断当前是否选择相对天数
        if (isInput.value == true) {
            form.value.timeType = 0;//类型赋值
            // 清空开始时间、结束时间
            form.value.gmtStart = 0;
            form.value.gmtEnd = 0
        } else {
            form.value.timeType = 1;
            form.value.days = null//切换绝对时间清空相对天数数据
        }
        // 判断当前是否选择全场3通用
        if (isCascader.value == true) {
            form.value.goodsType = 0;//类型赋值
            form.value.categoryId = 0// 清空指定类目
        } else {
            form.value.goodsType = 1
        }
    })

// 初始化数据
function init() {
    post(data.value).then((res) => {
        console.log(res);
        let { data: { items, total } } = res
        items.forEach((o: CouponClass) => {
            if (o.gmtEnd && o.gmtEnd < new Date().valueOf()) {
                o.status = -1
            }
        })
        tableData.value = items;//表格数据赋值
        pagination.value.total = total;//总页数赋值
    })
    categoryInfo()
}

// 导出当前表格
function derive() {
    /* generate workbook object from table */
    var xlsxParam = { raw: true } // 导出的内容只做解析，不进行格式转换
    var wb = XLSX.utils.table_to_book(document.querySelector('#exportTab'), xlsxParam)
    /* get binary string as output */
    var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
    try {
        FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), 'fileName.xlsx')
    } catch (e) {
        if (typeof console !== 'undefined') {
            console.log(e, wbout)
        }
    }
    return wbout
}

// 状态处理
function handleStatus(row: FormClass) {
    if (row.status == -1) {
        return '已过期'
    } else if (row.status == 0) {
        return '下架'
    } else if (row.status == 1) {
        return '正常'
    }
}

// 状态按钮处理
function handleStatusBtn(status: number) {
    if (status === 1) {
        return '冻结'
    } else if (status === 0) {
        return '激活'
    } else if (status < 0) {
        return '已过期'
    } else {
        return '错误状态'
    }
}

// 请求类目数据并处理
function categoryInfo() {
    post({ _gp: 'admin.category', _mt: 'categoryTree' }).then((res) => {
        console.log(res);
        let { data } = res;
        categoryData.value = data
    })
}

//指定开始时间
function getStartTime(value: number) {
    form.value.gmtStart = new Date(value).getTime()
}

//指定结束时间
function getEndTime(value: number) {
    form.value.gmtEnd = new Date(value).getTime()
}

// 类目数据赋值
function handleChange(value: number[]) {
    console.log(form.value.categoryId, value.slice(-1)[0])
    form.value.categoryId = value.slice(-1)[0]//截取数组最后一位并赋值
}

//添加
function handlePageAdd() {
    dialogType.value = false;//定义弹框类型
    dialogFormVisible.value = true;//显示弹框
    //判断有效期、商品限制范围
    isInput.value == true ? form.value.timeType = 0 : form.value.timeType = 1;
    isCascader.value == true ? form.value.goodsType = 0 : form.value.goodsType = 1;
    // 清空弹框表单
    form.value = (<FormClass>{});
    //重置控制弹框有效期、商品限制范围隐藏显示的布尔值
    isInput.value = true;
    isCascader.value = true
    ruleFormRef.value?.resetFields();//重置表单初始值
}

// 弹框确定添加优惠卷
function determine(formEl: FormInstance | undefined) {
    // 表单验证逻辑
    if (form.value.limit > form.value.total) {
        ElMessage.error('优惠券数量不能小于每人限领')
        return false
    } else if (form.value.discount >= form.value.min) { // 逻辑判断：最低消费金额 >= 优惠金额
        ElMessage.error('优惠金额不能高于等于最低消费')
        return false
    } else if (form.value.days == undefined && (form.value.gmtStart == undefined || form.value.gmtEnd == undefined)) {
        ElMessage.error('请填写优惠券的有效时间')  // 有效期逻辑处理：都为空的情况下触发提示
        return false
    } else if (form.value.goodsType === 0) {
        form.value.categoryId = undefined // 选择全场通用则指定分类为空
    }

    if (form.value.timeType == 1) { // 有效期逻辑处理：填写相对天数的情况下，绝对时间为空
        form.value.days = undefined
        if (!form.value.gmtStart || !form.value.gmtEnd || form.value.gmtEnd < form.value.gmtStart) {
            ElMessage.error('请正确选择日期')
            return false
        }
    } else {
        form.value.gmtStart = undefined;
        form.value.gmtEnd = undefined;
        if (form.value.days == undefined || form.value.days === 0) {
            ElMessage.error('请正确填写时长,不能为空或为0')
            return false
        }
    }

    if (!formEl) return
    formEl.validate((valid: boolean) => {
        if (valid) {
            post({ _gp: 'admin.coupon', _mt: 'create', ...form.value }).then((res) => {
                let { errmsg, errno } = res;
                200 == errno ? ElMessage.success('添加成功!') : ElMessage.error(errmsg);
                dialogFormVisible.value = false;//隐藏弹框
                init()
            })
        } else {
            return false
        }
    })
}

// 状态激活&冻结
function modifyState(index: number, row: FormClass) {
    if (row.status == -1) {
        ElMessage.error('优惠券已过期，请重新设置时间')
    } else {
        let state = row.status ? 0 : 1
        post({ _gp: 'admin.coupon', _mt: 'updateCouponStatus', id: row.id, status: state }).then((res) => {
            console.log(res);
            let { errmsg, errno } = res
            200 == errno ? ElMessage.success(state ? '激活成功' : '冻结成功') : ElMessage.error(errmsg)
            init()
        })
    }
}

// 查看
function survey(row: FormClass) {
    dialogType.value = true;//定义弹框类型
    dialogFormVisible.value = true;//显示弹框
    ruleFormRef.value?.resetFields();//重置表单初始值
    form.value = { ...row };
    row.days ? isInput.value = true : isInput.value = false; //判断显示有效期
    row.categoryId ? isCascader.value = false : isCascader.value = true; //判断显示商品限制范围
}

// 分页组件里的数据赋值
function handlePageChange(v: PaginationClass) {
    data.value.pageNo = v.page
    data.value.limit = v.limit
    init()
}
</script>
<style lang="less" scoped>
.grid-content {
    display: flex;
    margin-bottom: 30px;

    .m-2 {
        width: 230px;
        margin-right: 8px;
    }

    .el-select {
        margin-right: 8px;
    }
}

.el-form {
    margin: auto;
    width: 500px;

    .m-3 {
        margin: 15px 0px 0px 0px;
    }

    .picker {
        display: flex;
        width: 100%;
        flex-wrap: nowrap;
        margin: 15px 0px 0px 0px;

        span {
            margin: 0px 10px;
        }
    }

    .cascaderBox {
        width: 100%;
        display: flex;
        margin: 15px 0px;
        flex-wrap: nowrap;
    }
}
</style>